package com.xinqi.modules.prepare.question.manager.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinqi.common.base.current.Currents;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.mybatis.data.service.impl.BaseServiceImpl;
import com.xinqi.modules.prepare.folder.domain.PrepareFileFolderEntity;
import com.xinqi.modules.prepare.paper.dto.req.QuestionTypeNumDTO;
import com.xinqi.modules.prepare.prepare.enums.PrepareQuestionTypeEnum;
import com.xinqi.modules.prepare.question.convert.PrepareQuestionBankConvert;
import com.xinqi.modules.prepare.question.domain.PrepareQuestionBankEntity;
import com.xinqi.common.base.dto.QuestionBaseDTO;
import com.xinqi.modules.prepare.question.dto.QuestionScoreDTO;
import com.xinqi.modules.prepare.question.dto.QuestionSortDTO;
import com.xinqi.modules.prepare.question.dto.req.PrepareQuestionBankQueryDTO;
import com.xinqi.modules.prepare.question.dto.rsp.PrepareQuestionBankResultDTO;
import com.xinqi.modules.prepare.question.dto.rsp.PrepareQuestionStatsDataDTO;
import com.xinqi.modules.prepare.question.dto.rsp.QuestionTypeStatsDetail;
import com.xinqi.modules.prepare.question.manager.PrepareQuestionBankManager;
import com.xinqi.modules.prepare.question.mapper.PrepareQuestionBankMapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 备课区测评卷试题表管理层实现
 *
 * @author: system
 * @date: 2023/03/19
 */
@Service
@RequiredArgsConstructor
public class PrepareQuestionBankManagerImpl extends BaseServiceImpl<PrepareQuestionBankMapper, PrepareQuestionBankEntity> implements PrepareQuestionBankManager {

    private final PrepareQuestionBankConvert prepareQuestionBankConvert;

    /**
     * 自定义分页查询
     */
    @Override
    public Page<PrepareQuestionBankResultDTO> findPage(Page<Object> page, PrepareQuestionBankQueryDTO query) {
        return this.baseMapper.findPage(page, query);
    }

    /**
     * 自定义列表查询
     */
    @Override
    public List<PrepareQuestionBankResultDTO> findList(PrepareQuestionBankQueryDTO query) {
        return this.baseMapper.findList(query);
    }

    /**
     * 根据id查询 备课区测评卷试题表数据
     */
    @Override
    public PrepareQuestionBankEntity findById(Long id) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(id), "ID不能为空");
        return getById(id);
    }

    /**
     * 根据id删除 备课区测评卷试题表数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(Long id) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(id), "ID不能为空");
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editQuestionScore(Long prepareId, List<QuestionScoreDTO> scores) {
        return updateBatchById(
            scores.stream().map(v -> {
                PrepareQuestionBankEntity entity = new PrepareQuestionBankEntity();
                entity.setId(v.getId());
                entity.setScore(v.getScore());
                return entity;
            }).collect(Collectors.toList()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean sortQuestionBank(Long prepareId, List<QuestionSortDTO> sorts) {
        return updateBatchById(sorts.stream().filter(Objects::nonNull).map(v -> {
            PrepareQuestionBankEntity entity = new PrepareQuestionBankEntity();
            entity.setId(v.getId());
            entity.setSort(v.getSort());
            return entity;
        }).collect(Collectors.toList()));
    }

    @Override
    public PrepareQuestionStatsDataDTO questionStats(Long prepareId) {
        List<QuestionTypeStatsDetail> list = this.baseMapper.questionStats(prepareId);
        return PrepareQuestionStatsDataDTO.of(list);
    }

    @Override
    public long countByPrepareId(Long prepareId) {
        LambdaQueryWrapper<PrepareQuestionBankEntity> wrapper = new LambdaQueryWrapper<>();
        return count(wrapper.eq(PrepareQuestionBankEntity::getPrepareId, prepareId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void copy(Long id, PrepareFileFolderEntity target) {
        // TODO 武文杰 这个方法有问题
        PrepareQuestionBankEntity sources = findById(id);
        PrepareQuestionBankEntity copy = prepareQuestionBankConvert.copy(sources, new PrepareQuestionBankEntity());
        copy.setUserId(Currents.userId());
        copy.setPrepareId(target.getPrepareId());
        save(copy);
        target.setRefId(copy.getId());
    }

    @Override
    public List<QuestionBaseDTO> findByRandom(Long prepareId, List<QuestionTypeNumDTO> questionTypeNumList) {
        if (CollectionUtils.isEmpty(questionTypeNumList)) {
            return Collections.emptyList();
        }
        List<QuestionBaseDTO> list = new ArrayList<>(
            questionTypeNumList.stream().map(QuestionTypeNumDTO::getNum).reduce(0, Integer::sum)
        );
        // 随机获取题目
        for (QuestionTypeNumDTO typeNum : questionTypeNumList) {
            PrepareQuestionTypeEnum questionType = typeNum.getQuestionType();
            Integer num = typeNum.getNum();
            List<PrepareQuestionBankEntity> questionBanks = this.baseMapper.findByRandom(prepareId, questionType.getCode(), num);
            list.addAll(questionBanks.stream().map(prepareQuestionBankConvert::entity2Base).collect(Collectors.toList()));
        }
        return list;
    }

}
